package com.zjxny.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

import javax.annotation.Resource;
import javax.transaction.Transactional;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import com.zjxny.exception.TrafficException;
import com.zjxny.model.AccountInfo;
import com.zjxny.model.CarInfo;
import com.zjxny.model.CustomerInfo;
import com.zjxny.model.SmsInfo;
import com.zjxny.model.SmsTplInfo;
import com.zjxny.model.TrafficDetail;
import com.zjxny.model.TrafficInfo;
import com.zjxny.service.TrafficService;
import com.zjxny.utils.MinioUtil;
import com.zjxny.vo.ResponseSimpleVO;
import com.zjxny.vo.ResponseVO;
import com.zjxny.vo.TrafficDetailVO;
import com.zjxny.vo.TrafficVO;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.map.MapBuilder;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpDownloader;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import xyz.erupt.jpa.dao.EruptDao;

@Slf4j
@Service
public class TrafficServiceImpl implements TrafficService {

	@Resource
	private EruptDao eruptDao;
	
	@Resource
	private JdbcTemplate jdbcTemplate;

	@Value("${traffic.sleep:1000}")
	Long sleepTime;
	
	@Value("${traffic.monthOffset:-12}")
	Integer monthOffset;
	
	@Value("${minio.url}")
	String imageDomain;
	
	@Autowired
    private MinioUtil minioUtil;

	/**
	 * 获取违章数据
	 */
	@Override
	@Modifying
	@Transactional
//	@Async("taskExecutor")
	public List<TrafficVO> getTrafficList(CarInfo carInfo)  throws TrafficException{
		String domain = carInfo.getAccountInfo().getDomain();
		String cookieStr = carInfo.getAccountInfo().getCookies();
		String hphm = carInfo.getHphm();
		
		JSONArray arr = JSONUtil.parseArray(cookieStr);
		List<String> cookieArr = arr.stream().map(s -> {
			JSON t = (JSON) s;
			return String.format("%s=%s", t.getByPath("name", String.class), t.getByPath("value", String.class));
		}).collect(Collectors.toList());
		String cookies=StrUtil.join("; ", cookieArr);
		
		String url = String.format("https://%s/user/m/uservio/suriquery", domain);
		String referer = String.format("https://%s/views/memfyy/violation.html", domain);
		
		HttpRequest request = HttpRequest.post(url).header("Referer", referer);
		request.header("Cookie",cookies);
		request.header("User-Agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36");
		
		Date now = new Date();
		String stime = DateUtil.format(DateUtil.offsetMonth(now, monthOffset),DatePattern.PURE_DATE_PATTERN) ;//"20230101";
		String etime = DateUtil.format(now,DatePattern.PURE_DATE_PATTERN);

		MapBuilder<String, Object> builder =MapUtil.builder(new HashMap<String, Object>())
				.put("startDate", stime)
				.put("endDate", etime)
				.put("hpzl", 52)
				.put("hphm",hphm)
				.put("page", 1)
				.put("type", 0);
		HttpResponse response = request.form(builder.build()).execute();
		log.info("getTrafficList.carNo={},response={}",carInfo.getHphm(),response.body());
		
		if(response.getStatus() ==302) {
			String accountToUser = null!=carInfo.getAccountInfo()?carInfo.getAccountInfo().getNotifyCpName():"";
			String accountName = null!=carInfo.getAccountInfo()?carInfo.getAccountInfo().getSimpleTitle():"";
			throw new TrafficException("会话失效", -1,accountToUser,accountName);
		}
		
		if(response.getStatus()==200) {
			ResponseVO<TrafficVO> result = JSONUtil.toBean(response.body(), new TypeReference<ResponseVO<TrafficVO>>() {}, false);
			if(result.getCode()!=200){
				log.error("查询车辆{}违章失败,CODE={}，错误信息:{}",hphm,result.getCode(),result.getMessage());
				return null;
			}

			List<TrafficVO> traffics = result.getData().getContent();
			Iterator<TrafficVO> iter = traffics.iterator();
			while(iter.hasNext()) {
				TrafficVO trafficVO = iter.next();
				//获取违章详情
				TrafficDetailVO trafficDetailVO = getTrafficDetail(carInfo,trafficVO.getXh());
				
				if(StrUtil.isNotBlank(trafficDetailVO.getPhotos())) {
					trafficVO.setPhotos(trafficDetailVO.getPhotos());
				}
				
				if(null!=trafficDetailVO) {
					trafficVO.setWfjfs(trafficDetailVO.getWfjfs());
				}

				if(StrUtil.isNotBlank(trafficVO.getClsj())) {
					trafficVO.setClsj(trafficVO.getClsj().substring(0, 10));
				}

				if(StrUtil.isNotBlank(trafficVO.getWfsj())) {
					trafficVO.setWfsj(trafficVO.getWfsj().substring(0, 10));
				}
				if(StrUtil.isNotBlank(trafficDetailVO.getCjjgmc())) {
					trafficVO.setCjjgmc(trafficDetailVO.getCjjgmc());
				}
				if(StrUtil.isNotBlank(trafficDetailVO.getFkje())) {
					trafficVO.setFkje(trafficDetailVO.getFkje());
				}
			}
			//trafficVO 为引用对象,值发生改变
			syncTrafficSimple2DB(carInfo,traffics,carInfo.getAccountInfo());//写入数据

			if(result.getData().getLast()){
				return null;
			}

			//循环所有分页
			for(int i=2;i<=result.getData().getTotalPages();i++) {
				if(sleepTime>0) {
					long random = RandomUtil.randomLong(sleepTime);
					try {
						Thread.sleep(random);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				
				request = HttpRequest.post(url).header("Referer", referer);
				request.header("Cookie",cookies);
				request.header("User-Agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36");

				builder.clear();
				builder.put("startDate", stime)
						.put("endDate", etime)
						.put("hpzl", 52)
						.put("hphm",hphm)
						.put("page", i)
						.put("type", 0);
				response = request.form(builder.build()).execute();
				if(response.getStatus() ==302) {
					String accountToUser = null!=carInfo.getAccountInfo()?carInfo.getAccountInfo().getNotifyCpName():"";
					String accountName = null!=carInfo.getAccountInfo()?carInfo.getAccountInfo().getSimpleTitle():"";
					throw new TrafficException("会话失效", -1,accountToUser,accountName);
				}

				result = JSONUtil.toBean(response.body(), new TypeReference<ResponseVO<TrafficVO>>() {}, false);
				traffics = result.getData().getContent();
				iter = traffics.iterator();
				while(iter.hasNext()) {
					TrafficVO trafficVO = iter.next();
					TrafficDetailVO trafficDetailVO = getTrafficDetail(carInfo,trafficVO.getXh());
					if(StrUtil.isNotBlank(trafficDetailVO.getPhotos())) {
						trafficVO.setPhotos(trafficDetailVO.getPhotos());
					}

					if(null!=trafficDetailVO) {
						trafficVO.setWfjfs(trafficDetailVO.getWfjfs());
					}
					if(StrUtil.isNotBlank(trafficVO.getClsj())) {
						trafficVO.setClsj(trafficVO.getClsj().substring(0, 10));
					}
					if(StrUtil.isNotBlank(trafficVO.getWfsj())) {
						trafficVO.setWfsj(trafficVO.getWfsj().substring(0, 10));
					}
					if(StrUtil.isNotBlank(trafficDetailVO.getCjjgmc())) {
						trafficVO.setCjjgmc(trafficDetailVO.getCjjgmc());
					}
					if(StrUtil.isNotBlank(trafficDetailVO.getFkje())) {
						trafficVO.setFkje(trafficDetailVO.getFkje());
					}
				}
				syncTrafficSimple2DB(carInfo,traffics,carInfo.getAccountInfo());//写入数据
			}
		} else {
			log.warn("status={},body={}",response.getStatus(),response.body());
		}
		return null;
	}
	
	/**
	 * 获取违法详情
	 */
	@Modifying
	@Transactional
	@Override
	public TrafficDetailVO getTrafficDetail(CarInfo carInfo,String xh)  throws TrafficException{
		String cookieStr = carInfo.getAccountInfo().getCookies();
		if(StrUtil.isBlankIfStr(cookieStr)) {
			String accountToUser = null!=carInfo.getAccountInfo()?carInfo.getAccountInfo().getNotifyCpName():"";
			String accountName = null!=carInfo.getAccountInfo()?carInfo.getAccountInfo().getSimpleTitle():"";
			throw new TrafficException("会话失效", -1,accountToUser,accountName);
		}
		
		String domain = carInfo.getAccountInfo().getDomain();
		String hphm = carInfo.getHphm();
		TrafficDetailVO trafficDetailVO = getTrafficDetailOrigin(cookieStr,domain,hphm,xh);
		if(null!=trafficDetailVO) {
			syncTrafficDetail2DB(carInfo,trafficDetailVO);//写入数据
			return trafficDetailVO;
		}
		return null;
	}
	
	@Override
	public TrafficDetailVO getTrafficDetailOrigin(String cookieStr,String domain,String hphm,String xh) {
		JSONArray arr = JSONUtil.parseArray(cookieStr);
		List<String> cookieArr = arr.stream().map(s -> {
			JSON t = (JSON) s;
			return String.format("%s=%s", t.getByPath("name", String.class), t.getByPath("value", String.class));
		}).collect(Collectors.toList());
		String cookies=StrUtil.join("; ", cookieArr);
		
		String url = String.format("https://%s/user/m/tsc/vio/querySurvielDetail", domain);
		String referer = String.format("https://%s/views/memfyy/violation.html", domain);
		
		HttpRequest request = HttpRequest.post(url).header("Referer", referer);
		request.header("Cookie",cookies);
		request.header("User-Agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36");
		
		MapBuilder<String, Object> builder =MapUtil.builder(new HashMap<String, Object>())
				.put("xh",xh)
				.put("cjjg", "")
				.put("hpzl", "52")
				.put("hphm",hphm);
		HttpResponse response = request.form(builder.build()).execute();
		log.info("TrafficDetail carNo={},xh={},response={}",hphm,xh, response.body());
		
		if(response.getStatus()==200) {			
			ResponseSimpleVO<TrafficDetailVO> result = JSONUtil.toBean(response.body(), new TypeReference<ResponseSimpleVO<TrafficDetailVO>>() {}, false);
			if(null!=result) {
				TrafficDetailVO trafficDetailVO = result.getData();
				return trafficDetailVO;
			}
		}
		return null;
	}

	/**
	 * 查询车辆的违章列表-简情
	 * 
	 * @param carInfo
	 * @return
	 * @throws TrafficException
	 */
	@Override
	@Modifying
	@Transactional
//	@Async("taskExecutor")
	public List<TrafficVO> getOperationTrafficList(CarInfo carInfo)  throws TrafficException{
		String domain = carInfo.getAccountInfo().getDomain();
		String cookieStr = carInfo.getAccountInfo().getCookies();
		JSONArray arr = JSONUtil.parseArray(cookieStr);
		List<String> cookieArr = arr.stream().map(s -> {
			JSON t = (JSON) s;
			return String.format("%s=%s", t.getByPath("name", String.class), t.getByPath("value", String.class));
		}).collect(Collectors.toList());

		String cookies=StrUtil.join("; ", cookieArr);
		String url = String.format("https://%s/user/m/tsc/vio/querySurveilVeh", domain);
		String referer = String.format("https://%s/m/tsc/vehdetail", domain);

		HttpRequest request = HttpRequest.post(url).header("Referer", referer);

		request.header("Cookie",cookies);
		request.header("User-Agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36");

		MapBuilder<String, Object> builder =MapUtil.builder(new HashMap<String, Object>())
				.put("xh", carInfo.getXh())
				.put("page", 1)
				.put("size", 10);
		HttpResponse response = request.form(builder.build()).execute();
		log.info("getOperationTrafficList carNo={},response={}",carInfo.getHphm(),response.body());

		if(response.getStatus() ==302) {
			//获取当前公司主体信息
			String accountToUser = null!=carInfo.getAccountInfo()?carInfo.getAccountInfo().getNotifyCpName():"";
			String accountName = null!=carInfo.getAccountInfo()?carInfo.getAccountInfo().getSimpleTitle():"";
			throw new TrafficException("会话失效", -1,accountToUser,accountName);
		}
		if(response.getStatus()==200) {
			ResponseVO<TrafficVO> result = JSONUtil.toBean(response.body(), new TypeReference<ResponseVO<TrafficVO>>() {}, false);
			if(result.getCode()!=200){
				log.error("查询车辆{}违章失败,CODE={}，错误信息:{}",carInfo.getHphm(),result.getCode(),result.getMessage());
				return null;
			}

			List<TrafficVO> traffics = result.getData().getContent();
			Iterator<TrafficVO> iter = traffics.iterator();
			while(iter.hasNext()) {
				TrafficVO trafficVO = iter.next();
				
				//获取车辆违章详情
				TrafficDetailVO trafficDetailVO = getOperationTrafficDetail(carInfo,trafficVO.getXh(),trafficVO.getCjjg());
				if(StrUtil.isNotBlank(trafficDetailVO.getPhotos())) {
					trafficVO.setPhotos(trafficDetailVO.getPhotos());
				}
				
				if(null!=trafficDetailVO) {
					trafficVO.setWfjfs(trafficDetailVO.getWfjfs());
				}
				if(StrUtil.isNotBlank(trafficVO.getClsj())) {
					trafficVO.setClsj(trafficVO.getClsj().substring(0, 10));
				}

				if(StrUtil.isNotBlank(trafficVO.getWfsj())) {
					trafficVO.setWfsj(trafficVO.getWfsj().substring(0, 10));
				}

				if(StrUtil.isNotBlank(trafficDetailVO.getCjjgmc())) {
					trafficVO.setCjjgmc(trafficDetailVO.getCjjgmc());
				}
				if(StrUtil.isNotBlank(trafficDetailVO.getFkje())) {
					trafficVO.setFkje(trafficDetailVO.getFkje());
				}
			}
			syncTrafficSimple2DB(carInfo,traffics,carInfo.getAccountInfo());//写入数据

			//最后一页 直接返回
			if(result.getData().getLast()){
				return null;
			}

			//循环所有分页
			for(int i=2;i<=result.getData().getTotalPages();i++) {
				long random = RandomUtil.randomLong(1000l);//TODO 测试阶段先关闭
				try {
					Thread.sleep(random);
				} catch (Exception e) {
					e.printStackTrace();
				}

				request = HttpRequest.post(url).header("Referer", referer);
				request.header("Cookie",cookies);
				request.header("User-Agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36");

				builder.clear();
				builder.put("xh", carInfo.getXh())
						.put("page", i)
						.put("size", 10);
				response = request.form(builder.build()).execute();
				if(response.getStatus() ==302) {
					String accountToUser = null!=carInfo.getAccountInfo()?carInfo.getAccountInfo().getNotifyCpName():"";
					String accountName = null!=carInfo.getAccountInfo()?carInfo.getAccountInfo().getSimpleTitle():"";
					throw new TrafficException("会话失效", -1,accountToUser,accountName);
				}

				result = JSONUtil.toBean(response.body(), new TypeReference<ResponseVO<TrafficVO>>() {}, false);
				traffics = result.getData().getContent();
				iter = traffics.iterator();
				while(iter.hasNext()) {
					TrafficVO trafficVO = iter.next();
					
					TrafficDetailVO trafficDetailVO = getOperationTrafficDetail(carInfo,trafficVO.getXh(),trafficVO.getCjjg());
					if(StrUtil.isNotBlank(trafficDetailVO.getPhotos())) {
						trafficVO.setPhotos(trafficDetailVO.getPhotos());
					}
					
					if(null!=trafficDetailVO) {
						trafficVO.setWfjfs(trafficDetailVO.getWfjfs());
					}
					if(StrUtil.isNotBlank(trafficVO.getClsj())) {
						trafficVO.setClsj(trafficVO.getClsj().substring(0, 10));
					}

					if(StrUtil.isNotBlank(trafficVO.getWfsj())) {
						trafficVO.setWfsj(trafficVO.getWfsj().substring(0, 10));
					}

					if(StrUtil.isNotBlank(trafficDetailVO.getCjjgmc())) {
						trafficVO.setCjjgmc(trafficDetailVO.getCjjgmc());
					}
					if(StrUtil.isNotBlank(trafficDetailVO.getFkje())) {
						trafficVO.setFkje(trafficDetailVO.getFkje());
					}
				}
				syncTrafficSimple2DB(carInfo,traffics,carInfo.getAccountInfo());//写入数据
			}
		} else {
			log.warn("status={},body={}",response.getStatus(),response.body());
		}
		return null;
	}
	
	//业务车辆违章信息
	/**
	 * 租赁业务车辆违章列表
	 */
	@Override
	@Modifying
	@Transactional
	public List<TrafficVO> getBizTrafficList(CarInfo carInfo) throws TrafficException {
		String domain = carInfo.getAccountInfo().getDomain();
		String cookieStr = carInfo.getAccountInfo().getCookies();
		JSONArray arr = JSONUtil.parseArray(cookieStr);
		List<String> cookieArr = arr.stream().map(s -> {
			JSON t = (JSON) s;
			return String.format("%s=%s", t.getByPath("name", String.class), t.getByPath("value", String.class));
		}).collect(Collectors.toList());

		String cookies=StrUtil.join("; ", cookieArr);	
		String url = String.format("https://%s/user/m/rentveh/querySurveilList", domain);
		String referer = String.format("https://%s/views/memrent/vehdetail.html", domain);

		HttpRequest request = HttpRequest.post(url).header("Referer", referer);

		request.header("Cookie",cookies);
		request.header("User-Agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36");

		MapBuilder<String, Object> builder =MapUtil.builder(new HashMap<String, Object>())
				.put("xh", carInfo.getXh())
				.put("page", 1)
				.put("size", 10);
		HttpResponse response = request.form(builder.build()).execute();
		log.info("getOperationTrafficList carNo={},response={}",carInfo.getHphm(),response.body());

		if(response.getStatus() ==302) {
			//获取当前公司主体信息
			String accountToUser = null!=carInfo.getAccountInfo()?carInfo.getAccountInfo().getNotifyCpName():"";
			String accountName = null!=carInfo.getAccountInfo()?carInfo.getAccountInfo().getSimpleTitle():"";
			throw new TrafficException("会话失效", -1,accountToUser,accountName);
		}
		if(response.getStatus()==200) {
			ResponseVO<TrafficVO> result = JSONUtil.toBean(response.body(), new TypeReference<ResponseVO<TrafficVO>>() {}, false);
			if(result.getCode()!=200){
				log.error("查询车辆{}违章失败,CODE={}，错误信息:{}",carInfo.getHphm(),result.getCode(),result.getMessage());
				return null;
			}

			List<TrafficVO> traffics = result.getData().getContent();
			Iterator<TrafficVO> iter = traffics.iterator();
			while(iter.hasNext()) {
				TrafficVO trafficVO = iter.next();
				
				//获取违章详情
				TrafficDetailVO trafficDetailVO = getBizTrafficDetail(carInfo,trafficVO.getXh());
				if(StrUtil.isNotBlank(trafficDetailVO.getPhotos())) {
					trafficVO.setPhotos(trafficDetailVO.getPhotos());
				}
				
				if(null!=trafficDetailVO) {
					trafficVO.setWfjfs(trafficDetailVO.getWfjfs());
				}
				if(StrUtil.isNotBlank(trafficVO.getClsj())) {
					trafficVO.setClsj(trafficVO.getClsj().substring(0, 10));
				}

				if(StrUtil.isNotBlank(trafficVO.getWfsj())) {
					trafficVO.setWfsj(trafficVO.getWfsj().substring(0, 10));
				}

				if(StrUtil.isNotBlank(trafficDetailVO.getCjjgmc())) {
					trafficVO.setCjjgmc(trafficDetailVO.getCjjgmc());
				}
				if(StrUtil.isNotBlank(trafficDetailVO.getFkje())) {
					trafficVO.setFkje(trafficDetailVO.getFkje());
				}
			}
			syncTrafficSimple2DB(carInfo,traffics,carInfo.getAccountInfo());//写入数据

			//最后一页 直接返回
			if(result.getData().getLast()){
				return null;
			}

			//循环所有分页
			for(int i=2;i<=result.getData().getTotalPages();i++) {
				long random = RandomUtil.randomLong(1000l);//TODO 测试阶段先关闭
				try {
					Thread.sleep(random);
				} catch (Exception e) {
					e.printStackTrace();
				}

				request = HttpRequest.post(url).header("Referer", referer);
				request.header("Cookie",cookies);
				request.header("User-Agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36");

				builder.clear();
				builder.put("xh", carInfo.getXh())
						.put("page", i)
						.put("size", 10);
				response = request.form(builder.build()).execute();
				if(response.getStatus() ==302) {
					String accountToUser = null!=carInfo.getAccountInfo()?carInfo.getAccountInfo().getNotifyCpName():"";
					String accountName = null!=carInfo.getAccountInfo()?carInfo.getAccountInfo().getSimpleTitle():"";
					throw new TrafficException("会话失效", -1,accountToUser,accountName);
				}

				result = JSONUtil.toBean(response.body(), new TypeReference<ResponseVO<TrafficVO>>() {}, false);
				traffics = result.getData().getContent();
				iter = traffics.iterator();
				while(iter.hasNext()) {
					TrafficVO trafficVO = iter.next();					
					TrafficDetailVO trafficDetailVO = getBizTrafficDetail(carInfo,trafficVO.getXh());
					if(StrUtil.isNotBlank(trafficDetailVO.getPhotos())) {
						trafficVO.setPhotos(trafficDetailVO.getPhotos());
					}
					if(null!=trafficDetailVO) {
						trafficVO.setWfjfs(trafficDetailVO.getWfjfs());
					}
					if(StrUtil.isNotBlank(trafficVO.getClsj())) {
						trafficVO.setClsj(trafficVO.getClsj().substring(0, 10));
					}

					if(StrUtil.isNotBlank(trafficVO.getWfsj())) {
						trafficVO.setWfsj(trafficVO.getWfsj().substring(0, 10));
					}

					if(StrUtil.isNotBlank(trafficDetailVO.getCjjgmc())) {
						trafficVO.setCjjgmc(trafficDetailVO.getCjjgmc());
					}
					if(StrUtil.isNotBlank(trafficDetailVO.getFkje())) {
						trafficVO.setFkje(trafficDetailVO.getFkje());
					}
				}
				syncTrafficSimple2DB(carInfo,traffics,carInfo.getAccountInfo());//写入数据
			}
		} else {
			log.warn("status={},body={}",response.getStatus(),response.body());
		}
		return null;
	}
	

	/**
	 * 营运车违章详情
	 */
	@Override
	@Modifying
	@Transactional
	public TrafficDetailVO getOperationTrafficDetail(CarInfo carInfo, String xh,String cjjg)  throws TrafficException{
		String cookieStr = carInfo.getAccountInfo().getCookies();
		if(StrUtil.isBlankIfStr(cookieStr)) {
			String accountToUser = null!=carInfo.getAccountInfo()?carInfo.getAccountInfo().getNotifyCpName():"";
			String accountName = null!=carInfo.getAccountInfo()?carInfo.getAccountInfo().getSimpleTitle():"";
			throw new TrafficException("会话失效", -1,accountToUser,accountName);
		}
		String domain = carInfo.getAccountInfo().getDomain();
		TrafficDetailVO trafficDetailVO = getOperationTrafficDetailOrigin(cookieStr,domain,carInfo.getHphm(),xh,cjjg);
		if(null!=trafficDetailVO) {
			syncTrafficDetail2DB(carInfo,trafficDetailVO);//写入数据
			return trafficDetailVO;
		}
		return null;
	}
	
	/**
	 * 营运车的违章详情获取
	 * 
	 * @param cookieStr
	 * @param domain
	 * @param hphm
	 * @param xh
	 * @param cjjg
	 * @return
	 */
	@Override
	public TrafficDetailVO getOperationTrafficDetailOrigin(String cookieStr,String domain,String hphm,String xh,String cjjg) {
		JSONArray arr = JSONUtil.parseArray(cookieStr);
		List<String> cookieArr = arr.stream().map(s -> {
			JSON t = (JSON) s;
			return String.format("%s=%s", t.getByPath("name", String.class), t.getByPath("value", String.class));
		}).collect(Collectors.toList());
		String cookies=StrUtil.join("; ", cookieArr);

		String url = String.format("https://%s/user/m/tsc/vio/querySurvielDetail", domain);
		String referer = String.format("https://%s/m/tsc/vehdetail", domain);

		HttpRequest request = HttpRequest.post(url).header("Referer", referer);
		request.header("Cookie",cookies);
		request.header("User-Agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36");

		MapBuilder<String, Object> builder =MapUtil.builder(new HashMap<String, Object>())
				.put("xh",xh)
				.put("cjjg", cjjg)
				.put("hpzl", "52")
				.put("hphm",hphm);
		HttpResponse response = request.form(builder.build()).execute();
		log.info("getOperationTrafficDetail carNo={},xh={},response={}",hphm,xh, response.body());

		if(response.getStatus()==200) {
			ResponseSimpleVO<TrafficDetailVO> result = JSONUtil.toBean(response.body(), new TypeReference<ResponseSimpleVO<TrafficDetailVO>>() {}, false);
			if(null!=result) {
				TrafficDetailVO trafficDetailVO = result.getData();
				return trafficDetailVO;
			}
		}
		return null;
	}
	
	//业务类型--违章详情

	/**
	 * 租赁车辆 
	 */
	@Override
	@Modifying
	@Transactional
	public TrafficDetailVO getBizTrafficDetail(CarInfo carInfo, String xh)  throws TrafficException{
		String cookieStr = carInfo.getAccountInfo().getCookies();
		if(StrUtil.isBlankIfStr(cookieStr)) {
			String accountToUser = null!=carInfo.getAccountInfo()?carInfo.getAccountInfo().getNotifyCpName():"";
			String accountName = null!=carInfo.getAccountInfo()?carInfo.getAccountInfo().getSimpleTitle():"";
			throw new TrafficException("会话失效", -1,accountToUser,accountName);
		}
		TrafficDetailVO trafficDetailVO = getBizTrafficDetailOrigin(cookieStr,carInfo.getAccountInfo().getDomain(),carInfo.getHphm(),carInfo.getXh(),xh);
		if(null!=trafficDetailVO) {
			syncTrafficDetail2DB(carInfo,trafficDetailVO);//写入数据
			return trafficDetailVO;
		}
		return null;
	}
	
	@Override
	public TrafficDetailVO getBizTrafficDetailOrigin(String cookieStr,String domain,String hphm,String carInfoXh,String trafficXh) {
		JSONArray arr = JSONUtil.parseArray(cookieStr);
		List<String> cookieArr = arr.stream().map(s -> {
			JSON t = (JSON) s;
			return String.format("%s=%s", t.getByPath("name", String.class), t.getByPath("value", String.class));
		}).collect(Collectors.toList());
		String cookies=StrUtil.join("; ", cookieArr);

		String url = String.format("https://%s/vio/rent/surveil/detail", domain);
		String referer = String.format("https://%s/views/memrent/vehdetail.html", domain);

		HttpRequest request = HttpRequest.post(url).header("Referer", referer);
		request.header("Cookie",cookies);
		request.header("User-Agent","Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36");

		MapBuilder<String, Object> builder =MapUtil.builder(new HashMap<String, Object>())
				.put("xh",carInfoXh)
				.put("fxcxh", trafficXh);
		
		HttpResponse response = request.form(builder.build()).execute();
		log.info("getBizTrafficDetail carNo={},xh={},response={}",hphm,carInfoXh, response.body());

		if(response.getStatus()==200) {
			ResponseSimpleVO<TrafficDetailVO> result = JSONUtil.toBean(response.body(), new TypeReference<ResponseSimpleVO<TrafficDetailVO>>() {}, false);
			if(null!=result) {
				TrafficDetailVO trafficDetailVO = result.getData();
				return trafficDetailVO;
			}
		}
		return null;
	}
	

	//写入违章详情
	@Modifying
	@Transactional
	public void syncTrafficDetail2DB(CarInfo carInfo,TrafficDetailVO trafficDetailVO) {
		TrafficDetail trafficDetail = eruptDao.queryEntity(TrafficDetail.class, "xh='"+trafficDetailVO.getXh()+"'");
		Boolean downImageFlag = false;
		if(null==trafficDetail) {
			trafficDetail = new TrafficDetail();
			trafficDetail.setAccountInfo(carInfo.getAccountInfo());
			trafficDetail.setCreateTime(new Date());
			
			if(StrUtil.isNotBlank(trafficDetailVO.getPhotos())) {				
				downImageFlag = true;
			}
		}
		
		BeanUtils.copyProperties(trafficDetailVO, trafficDetail);
		
		//下载图片
//		if(StrUtil.isNotBlank(trafficDetailVO.getPhotos()) && (StrUtil.isEmptyIfStr(trafficDetail.getPhotos()) || !trafficDetail.getPhotos().startsWith("upload"))) {
		if(downImageFlag) {
			log.info("start download photo, carInfo hphm={},xh={}",trafficDetailVO.getHphm(),trafficDetailVO.getXh());
			List<String> photos = JSONUtil.toBean(trafficDetailVO.getPhotos(),new TypeReference<List<String>>(){},false);
			List<String> photoUrls = new ArrayList<String>();
			for(String photo:photos) {
				try {					
					byte[] photoBytes = HttpDownloader.downloadBytes(photo);
					String fileName= trafficDetailVO.getXh()+RandomUtil.randomInt(10000)+".jpg";
					String photoUrl = minioUtil.upload(fileName,photoBytes);
					photoUrls.add(photoUrl);
				} catch (Exception e) {
					log.error("get photo url is fail. photo={}",photo);
					e.printStackTrace();
				}
			}
			
			String photoUrlStr = StrUtil.join(",", photoUrls);
			trafficDetail.setPhotos(photoUrlStr);
			trafficDetailVO.setPhotos(photoUrlStr);
		}
		
		trafficDetail.setUpdateTime(new Date());
		eruptDao.persistAndFlush(trafficDetail);
	}
	
	@Override
	public String downloadPhotos(String trafficXh,String photoStr){
		try {
			List<String> photos = JSONUtil.toBean(photoStr,new TypeReference<List<String>>(){},false);
			List<String> photoUrls = new ArrayList<String>();
			for(String photo:photos) {
				byte[] photoBytes = HttpDownloader.downloadBytes(photo);
				String fileName= trafficXh+RandomUtil.randomInt(10000)+".jpg";
				String photoUrl = minioUtil.upload(fileName,photoBytes);
				photoUrls.add(photoUrl);
			}
			return  StrUtil.join(",", photoUrls);			
		} catch (Exception e) {
			System.err.println("trafficXh="+trafficXh+"; photoStr="+photoStr);
			e.printStackTrace();
		}
		return "";
	}
	
	
	/**
	 * 同步数据至数据库中
	 * 
	 * @param
	 */
	@Modifying
	@Transactional
	public void syncTrafficSimple2DB(CarInfo carInfo,List<TrafficVO> traffics,AccountInfo accountInfo) {
		if(null==traffics || traffics.isEmpty()) {
			return;
		}

		for (TrafficVO trafficVO : traffics) {
			TrafficInfo trafficInfo = eruptDao.queryEntity(TrafficInfo.class, "xh='"+trafficVO.getXh()+"'");
			if(null == trafficInfo) {
				trafficInfo = new TrafficInfo();
				trafficInfo.setCreateTime(new Date());

				//新增车辆信息
				trafficInfo.setCarInfo(carInfo);
				Date ctime = new Date();
				//写入短信
				if("0".equals(trafficVO.getClbj())) {
					SmsInfo sms = new SmsInfo();
					sms.setAccountInfo(accountInfo);
					/**
					 尊敬的${custom}：您在我司租赁车辆:${carno}于${time}日在${address}违法(${trafficContent},记分:${score},罚款:${money}元)，请于短信发送之日起5日内处理清结，否则视为违约，我司有权按合同约定处理！
					 */
					CustomerInfo cus = trafficInfo.getCarInfo().getCustomerInfo();
					if(null!=cus){
						String content = String.format("亲爱的用户,您的用车%s于%s在%s违法,违法内容:%s,扣%s分,罚款%s元,请务必于5日内处理清结,以免造成其他次生损失! 客服电话:4000011290"
								,trafficVO.getHphm()
								,trafficVO.getWfsj()
								,trafficVO.getWfdz()
								,trafficVO.getWfms()
								,trafficVO.getWfjfs()
								,trafficVO.getFkje()
						);
						sms.setContent(content);
						sms.setCreateTime(ctime);
					}
					
					sms.setUpdateTime(ctime);
					SmsTplInfo smsTplInfo = eruptDao.queryEntity(SmsTplInfo.class, "id=1");
					sms.setSmsTplInfo(smsTplInfo);//设置发送短信模板
					sms.setType(1);//默认短信为违章初次发生时的类型
					sms.setXh(trafficVO.getXh());
					sms.setHphm(trafficVO.getHphm());
					
					//超过三个月的不用发送
					Date wfsj = DateUtil.offsetMonth(DateUtil.parse(trafficVO.getWfsj()), 3);
					if(wfsj.getTime()<System.currentTimeMillis()) {
						sms.setStatus(100);
					} else {
						sms.setStatus(0);
					}
					sms.setTrafficInfo(trafficInfo);
					sms.setCustomerInfo(cus);
					
					eruptDao.persist(sms);
				}
			} else if("0".equals(trafficInfo.getClbj()) || "0".equals(trafficInfo.getClbj()) ) {	
				//此处的处理是为了减少发短信
				if("1".equals(trafficVO.getClbj())) {
					String usql = "update sms_info set status=2 where xh='"+trafficVO.getXh()+"'";
					int affectNum= jdbcTemplate.update(usql);
					log.info("hphp={},xh={},affectNum={}",trafficVO.getHphm(),trafficVO.getXh(),affectNum);
				}
			}

			//写入发短信通知
			BeanUtils.copyProperties(trafficVO,trafficInfo,"wfsj","clsj");
			if(StrUtil.isNotBlank(trafficVO.getWfsj())){
				trafficInfo.setWfsj(DateUtil.parse(trafficVO.getWfsj()).toJdkDate());
			}
			if(StrUtil.isNotBlank(trafficVO.getClsj())){
				trafficInfo.setClsj(DateUtil.parse(trafficVO.getClsj()).toJdkDate());
			}
			trafficInfo.setAccountInfo(accountInfo);
			trafficInfo.setUpdateTime(new Date());
			eruptDao.persistAndFlush(trafficInfo);
		}
	}	
}